function subPopIndices = hierarchicalClustering(Population, fitnessValues, params)
    % 手动实现自下而上的聚类并自定义停止
    N = length(Population);
    if N <= 1
        subPopIndices = {1:N}; % 单集群
        return;
    end

    % 初始状态：每个个体都是一个簇{index}
    clusters = cell(N, 1);
    for i = 1:N
        clusters{i} = i;
    end

    % 预先计算所有成对距离（对于较大的 N 值，速度可能会比较慢）
    % 使用简单的距离度量进行结构测试 - 如有需要，可替换
    distMatrix = inf(N, N);% 创建一个大小为 N × N 的矩阵 distMatrix，
    % 每个元素初始值为正无穷 (inf)。这个矩阵用于存储种群中个体之间的距离
    for i = 1:N
        for j = i+1:N
             distMatrix(i,j) = calculateDistance(Population{i}, Population{j});
             distMatrix(j,i) = distMatrix(i,j); % 对称
        end
    end

    currentNumClusters = N;
    while currentNumClusters > 1
        % 计算平均簇间距离
        clusterDists = []; % 初始化一个空数组，用于存储当前轮次中所有有效簇对之间的平均距离。
        minClusterDist = inf; % 初始化当前最小簇间距离为正无穷
        mergeIndices = [-1, -1]; % *当前*“集群”列表中的索引

        validClusters = find(~cellfun('isempty', clusters)); % 非空集群的索引
        numValidClusters = length(validClusters);
        
        if numValidClusters <= 1; break; end % 如果只剩下一个簇，则停止

        avgDistances = zeros(numValidClusters, numValidClusters); % 储存平均分布

        for c1_idx = 1:numValidClusters % 外层循环遍历当前还有效的簇 cluster1
            cluster1_global_indices = clusters{validClusters(c1_idx)}; % 拿到一个簇的全部个体索引
            for c2_idx = c1_idx + 1:numValidClusters % 内层循环遍历 所有尚未比较过的簇 
                % cluster2（注意只从 c1_idx+1 开始，避免重复计算）
                cluster2_global_indices = clusters{validClusters(c2_idx)};

                % 计算cluster1和cluster2中个体之间的平均距离
                dists_between = distMatrix(cluster1_global_indices, cluster2_global_indices);
                avg_dist = mean(dists_between(:), 'omitnan'); % 平均距离

                if isnan(avg_dist); avg_dist = inf; end

                avgDistances(c1_idx, c2_idx) = avg_dist;
                avgDistances(c2_idx, c1_idx) = avg_dist;
                clusterDists = [clusterDists, avg_dist]; % 存储平均值计算

                if avg_dist < minClusterDist
                    minClusterDist = avg_dist;
                     % 将索引存储在*validClusters 列表中*
                    mergeIndices = [c1_idx, c2_idx];
                end
            end
        end

        if isinf(minClusterDist) || mergeIndices(1) == -1 % 不再可能合并了吗？
            break; 
        end

        % 检查停止标准（公式 4.4）
        meanDist_H = mean(clusterDists, 'omitnan');
        if ~isnan(meanDist_H) && meanDist_H > 1e-9 % 避免除以零或空 dists
            if abs(minClusterDist - meanDist_H) / meanDist_H <= params.ClusterSimilarityThresholdA
                fprintf('Clustering stopped: Min dist %.4f within %.1f%% of mean dist %.4f.\n', ...
                        minClusterDist, params.ClusterSimilarityThresholdA*100, meanDist_H);
                break; % 停止合并
            end
        end

        % 执行合并
        % 获取主“集群”列表中的实际索引
        mergeIdx1_in_clusters = validClusters(mergeIndices(1));
        mergeIdx2_in_clusters = validClusters(mergeIndices(2));
        
        % 将集群 2 中的索引合并到集群 1
        clusters{mergeIdx1_in_clusters} = [clusters{mergeIdx1_in_clusters}, clusters{mergeIdx2_in_clusters}];
        % 空集群 2
        clusters{mergeIdx2_in_clusters} = []; 
        currentNumClusters = currentNumClusters - 1;

    end % 结束 while 循环

    % 格式化输出：非空聚类索引向量的单元格数组
    subPopIndices = clusters(~cellfun('isempty', clusters));

end